/*
 * HashRecordSerializer.cpp
 *
 *  Created on: Oct 26, 2012
 *      Author: m
 */

#include <cassert>
#include <exception>
#include "HashRecordSerializer.h"

physical::VariableStringSerializer HashRecordSerializer::sm_stringSerializer;

HashRecordSerializer::HashRecordSerializer()
{
}

HashRecordSerializer::~HashRecordSerializer()
{
}

size_t HashRecordSerializer::serialize( const HashRecord &element, physical::byteStream block )
{
    physical::byte* blockPtr = block;
    RecordID id = element.getId();
    size_t lastOperationBytesCount;
    size_t totalBytesCount = 0;
    _str_ptr stringBuffer;

    // Serializo el id
    memcpy( blockPtr, &id, sizeof( RecordID ) );
    totalBytesCount += sizeof( RecordID );
    blockPtr += totalBytesCount;

    // serializo los 3 campos de string variable

    // Primero la frase
    stringBuffer.reset(new std::string);
    *stringBuffer = element.getFrase();
    lastOperationBytesCount = sm_stringSerializer.serialize( stringBuffer, blockPtr);
    totalBytesCount += lastOperationBytesCount;
    blockPtr += lastOperationBytesCount;

    //después el apellido del autor
    *stringBuffer = element.getAutorApellido();
    lastOperationBytesCount = sm_stringSerializer.serialize( stringBuffer, blockPtr);
    totalBytesCount += lastOperationBytesCount;
    blockPtr += lastOperationBytesCount;

    //finalmente el nombre del autor
    *stringBuffer = element.getAutorNombre();
    lastOperationBytesCount = sm_stringSerializer.serialize( stringBuffer, blockPtr);
    totalBytesCount += lastOperationBytesCount;
    blockPtr += lastOperationBytesCount;

    return totalBytesCount;
}

size_t HashRecordSerializer::deserialize( const physical::byteStream block, HashRecord &element )
{
    // TODO: Indicar correctamente: "método no implementado"
    throw "method not implemented";
    return 0;
}

size_t HashRecordSerializer::computeSize( const HashRecord &element )
{
    size_t totalBytesCount;

    totalBytesCount = sizeof( RecordID );

    // serializo los 3 campos de string variable (frase, apellido del autor y nombre del autor)

    totalBytesCount += sm_stringSerializer.computeSize( element.getFrase() );
    totalBytesCount += sm_stringSerializer.computeSize( element.getAutorApellido() );
    totalBytesCount += sm_stringSerializer.computeSize( element.getAutorNombre() );

    return totalBytesCount;
}

size_t HashRecordSerializer::serialize( const _T_ptr &elementPtr, physical::byteStream block )
{
    return this->serialize( *elementPtr, block );
};

size_t HashRecordSerializer:: HashRecordSerializer::deserialize( const physical::byteStream block, _T_ptr &elementPtr )
{
    physical::byte* blockPtr = (physical::byte*) block;
    RecordID id;
    size_t lastOperationBytesCount;
    _str_ptr phraseBuffer;
    _str_ptr surnameBuffer;
    _str_ptr nameBuffer;

    size_t bytesCount;

    // Serializo el id
    memcpy( &id, blockPtr, sizeof( RecordID ) );
    bytesCount = sizeof( RecordID );
    blockPtr += bytesCount;

    // Despues leo la frase
    lastOperationBytesCount = sm_stringSerializer.deserialize( blockPtr, phraseBuffer );
    bytesCount += lastOperationBytesCount;
    blockPtr += lastOperationBytesCount;

    // Despues leo el apellido del autor
    lastOperationBytesCount = sm_stringSerializer.deserialize( blockPtr, surnameBuffer );
    bytesCount += lastOperationBytesCount;
    blockPtr += lastOperationBytesCount;

    // Finalmente leo el nombre del autor
    lastOperationBytesCount = sm_stringSerializer.deserialize( blockPtr, nameBuffer );
    bytesCount += lastOperationBytesCount;

    elementPtr.reset( new HashRecord( id, *phraseBuffer, *surnameBuffer, *nameBuffer ) );

    return bytesCount;
};

size_t HashRecordSerializer::computeSize( const _T_ptr &elementPtr )
{
    return this->computeSize( *elementPtr );
};
